/*
 * FilePipelineCache.java
 *
 * Created on December 31, 2004, 12:02 PM
 */

package com.smallx.xproc.util;

import com.smallx.xproc.*;
import com.smallx.xproc.compiler.StreamingCompiler;
import java.net.*;
import java.io.*;
import java.util.*;
import org.infoset.xml.Document;
import org.infoset.xml.DocumentLoader;
import org.infoset.xml.Name;
import org.infoset.xml.XMLException;
import org.infoset.xml.sax.SAXDocumentLoader;
import org.infoset.component.ComponentRegistry;
import org.infoset.xproc.Pipeline;

/**
 *
 * @author R. Alexander Milowski
 */
public class FilePipelineCache extends PipelineCache
{
   
   Map timestamps;
   DocumentLoader docLoader;
   StreamingCompiler compiler;
   
   /** Creates a new instance of FilePipelineCache */
   public FilePipelineCache(boolean checkForChanges,DocumentLoader loader)
      throws XMLException
   {
      super(checkForChanges);
      this.timestamps = new HashMap();
      this.docLoader = loader;
      this.compiler = new StreamingCompiler();
   }
   
   public FilePipelineCache(boolean checkForChanges) 
      throws XMLException
   {
      super(checkForChanges);
      this.timestamps = new HashMap();
      this.docLoader = new SAXDocumentLoader();
      this.compiler = new StreamingCompiler();
   }
   
   public void setComponentRegistry(ComponentRegistry registry) {
      compiler.setComponentRegistry(registry);
   }
   
   protected boolean isUpToDate(URI id) {
      Long timestamp = (Long)timestamps.get(id);
      File f = new File(id.getSchemeSpecificPart());
      return timestamp==null ? false : timestamp.longValue()==f.lastModified();
   }
   /**
    * 
    * @param id 
    * @throws com.smallx.xml.infoset.XMLException 
    * @return 
    */
   protected Pipeline loadPipelineInstance(URI id) throws XMLException
   {
      Long timestamp = (Long)timestamps.get(id);
      try {
         File f = new File(id.getSchemeSpecificPart());
         if (!f.isFile()) {
            throw new XMLException("Path is not an XML file: "+f.getAbsolutePath());
         }
         Document pipeDoc = docLoader.load(id);
         Pipeline pipe = compiler.compile(pipeDoc.getDocumentElement());
         File base = f.getParentFile();
         if (timestamp==null) {
            synchronized (timestamps) {
               timestamps.put(id,new Long(f.lastModified()));
            }
         }
         return pipe;
      } catch (IOException ex) {
         throw new XMLException("I/O error while parsing pipeline file "+id,ex);
      }
   }
   
}
